package com.cskaoyan.service.kylan;

import com.cskaoyan.bean.*;
import com.cskaoyan.bean.params.BaseParam;
import com.cskaoyan.bean.wx.CouponListVO;
import com.cskaoyan.bean.wx.CouponMylistVO;
import com.cskaoyan.mapper.*;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.List;


@Service
public class WxCouponServiceImpl implements WxCouponService {

    @Autowired
    CouponUserMapper userMapper;
    @Autowired
    CouponMapper couponMapper;
    @Autowired
    GrouponRulesMapper grouponRulesMapper;
    @Autowired
    CartMapper cartMapper;
    @Autowired
    GoodsMapper goodsMapper;

    /**
     * 显示未领取过得优惠券（user还可以继续领取，优惠券状态status为0，deleted为0）
     * 涉及表格：coupon，coupon-user;
     *
     * @param baseParam
     * @param userId
     * @return
     */
    @Override
    public CouponListVO getCouponList(BaseParam baseParam, Integer userId) {

        CouponListVO couponListVO = new CouponListVO();
        //分页
        Integer limit = baseParam.getLimit();
        Integer page = baseParam.getPage();
        if (limit == null || page == 0) {
            return couponListVO;
        }

        PageHelper.startPage(page, limit);

        //根据userId获取当前用户已领取的优惠券id
        CouponUserExample userExample = new CouponUserExample();
        userExample.createCriteria().andUserIdEqualTo(userId);
        List<CouponUser> couponUsers = userMapper.selectByExample(userExample);

        List<Integer> couponHasIds = new ArrayList<>();
        for (CouponUser couponUser : couponUsers) {
            couponHasIds.add(couponUser.getCouponId());
        }

        //判断该优惠券是否可以继续领取，如果可以，则从couponHasIds中去掉；
        for (Integer couponHasId : couponHasIds) {
            Coupon coupon = couponMapper.selectByPrimaryKey(couponHasId);
            Integer limitNum = coupon.getLimit().intValue();
            if (limitNum != 1) {
                int index = couponHasIds.indexOf(couponHasId);
                couponHasIds.remove(index);
            }
        }
        //至此，couponHasIds为用户已持有，且不能继续领取的优惠券id集合


        //获取优惠券状态status为0，deleted为0的优惠券id；
        CouponExample couponExample = new CouponExample();
        couponExample.setOrderByClause(baseParam.getSort() + " " + baseParam.getOrder());
        Short status = 0;
        couponExample.createCriteria().andDeletedEqualTo(false).andStatusEqualTo(status);

        List<Coupon> coupons = couponMapper.selectByExample(couponExample);

        List<Integer> couponAllIds = new ArrayList<>();
        for (Coupon coupon : coupons) {
            couponAllIds.add(coupon.getId());
        }

        //得到可领取的优惠券id；
        couponAllIds.removeAll(couponHasIds);

        //根据couponIds，得到可领取的、未持有的优惠券信息；
        List<Coupon> couponList = new ArrayList<>();
        for (Integer couponId : couponAllIds) {
            Coupon coupon = couponMapper.selectByPrimaryKey(couponId);
            couponList.add(coupon);
        }

        //返回视图；
        couponListVO.setLimit(limit);
        couponListVO.setList(couponList);
        couponListVO.setPage(page);
        couponListVO.setTotal(couponList.size());
        couponListVO.setPages(couponList.size() / limit + 1);


        return couponListVO;
    }

    /**
     * 显示我的优惠券信息；
     *
     * @param baseParam
     * @param userId
     * @param status
     * @return
     */
    @Override
    public CouponMylistVO getMyCouponList(BaseParam baseParam, Integer userId, Integer status) {

        List<CouponMylistVO.ListEntity> myCouponList = couponMapper.selectMyCouponList(baseParam, userId, status);

        CouponMylistVO couponMylistVO = new CouponMylistVO();

        couponMylistVO.setLimit(baseParam.getLimit());
        couponMylistVO.setList(myCouponList);
        couponMylistVO.setPage(baseParam.getPage());
        couponMylistVO.setTotal(myCouponList.size());
        couponMylistVO.setPages(myCouponList.size() / baseParam.getPage() + 1);

        return couponMylistVO;
    }

    /**
     * 购物车下单查找可用的优惠券list；
     *
     * @param cartId
     * @param grouponRulesId
     * @param userId
     * @return
     */
    @Override
    public CouponMylistVO getSelectCouponList(Integer cartId, Integer grouponRulesId, Integer userId) {

        //1.获取全商品可使用的优惠券信息；goods_type=0
        CouponExample couponExample = new CouponExample();
        couponExample.createCriteria().andDeletedEqualTo(false).andGoodsTypeEqualTo(((short) 0));
        List<Coupon> couponList = couponMapper.selectByExample(couponExample);
        LinkedHashSet<Coupon> list = new LinkedHashSet<>();
        list.addAll(couponList);


        //2.获取类目限制的优惠券；
        //根据userId获取该用户购物车中处于选中状态（checked）的categoryIds；
        Integer deleted = 0;
        Integer checked = 0;

        //categoryIdsLike为[%categoryId%,...]
        List<Integer> categoryIdsLike = cartMapper.selectGoodTypeByUserId(userId, deleted, checked);
        for (Integer element : categoryIdsLike) {
            couponExample.clear();
            couponExample.createCriteria()
                    .andDeletedEqualTo(false)
                    .andGoodsTypeEqualTo(((short) 1))
                    .andGoodsValueLike("%" + element + "%");
            List<Coupon> coupons1 = couponMapper.selectByExample(couponExample);
            list.addAll(coupons1);
        }

        //3.获取商品限制的优惠券；（goodsType=2）
        List<Integer> goodsIds = couponMapper.selectGoodsIdsByUserId(userId, deleted, checked);
        for (Integer goodsId : goodsIds) {
            couponExample.clear();
            couponExample.createCriteria()
                    .andDeletedEqualTo(false)
                    .andGoodsTypeEqualTo(((short) 2))
                    .andGoodsValueLike("%" + goodsId + "%");
            List<Coupon> coupon2 = couponMapper.selectByExample(couponExample);
            list.addAll(coupon2);
        }

        //4.处理list
        CouponMylistVO couponMylistVO = new CouponMylistVO();
        List<CouponMylistVO.ListEntity> couponMylistVOList = new ArrayList<>();
        for (Coupon coupon : list) {
            CouponMylistVO.ListEntity listEntity = new CouponMylistVO.ListEntity();
            listEntity.setId(coupon.getId());
            listEntity.setCid(coupon.getId());
            listEntity.setDesc(coupon.getDesc());
            listEntity.setDiscount(coupon.getDiscount().doubleValue());
            listEntity.setEndTime(coupon.getEndTime().toString());
            listEntity.setMin(coupon.getMin().doubleValue());
            listEntity.setName(coupon.getName());
            listEntity.setStartTime(coupon.getStartTime().toString());
            listEntity.setTag(coupon.getTag());
            couponMylistVOList.add(listEntity);
        }


        //5.赋值
        couponMylistVO.setLimit(list.size());
        couponMylistVO.setPages(1);
        couponMylistVO.setPage(1);
        couponMylistVO.setTotal(list.size());
        couponMylistVO.setList(couponMylistVOList);

        return couponMylistVO;
    }

    /**
     * 首页领取优惠券
     *
     * @param userId
     * @param couponId
     * @return
     */
    @Override
    public Integer receiveCoupon(Integer userId, Integer couponId) {

        CouponUserExample userExample = new CouponUserExample();
        userExample.createCriteria()
                .andDeletedEqualTo(false)
                .andUserIdEqualTo(userId)
                .andCouponIdEqualTo(couponId);

        List<CouponUser> couponUsers = userMapper.selectByExample(userExample);

        if (couponUsers != null && couponUsers.size() != 0) {
            return 1;
        }

        //couponUsers为null，说明当前user未领取该优惠券（couponId）
        //获取该优惠券信息
        Coupon coupon = couponMapper.selectByPrimaryKey(couponId);

        //将优惠券信息存入coupon_user表中
        CouponUser user = new CouponUser();
        user.setUserId(userId);
        user.setCouponId(couponId);
        user.setStatus(coupon.getStatus());
        user.setStartTime(coupon.getStartTime());
        user.setEndTime(coupon.getEndTime());
        Date date = new Date();
        user.setAddTime(date);
        user.setUpdateTime(date);
        user.setDeleted(false);
        userMapper.insertSelective(user);

        return 0;
    }

    @Override
    public Integer receiveByExchangeCode(Integer userId, String code) {

        //1.先根据code在coupon中查询，确认code是否正确
        //若不正确，则返回 2；
        CouponExample couponExample = new CouponExample();
        Date date = new Date();
        couponExample.createCriteria()
                .andDeletedEqualTo(false)
                .andCodeEqualTo(code)
                .andEndTimeGreaterThan(date);
        List<Coupon> couponList = couponMapper.selectByExample(couponExample);
        if (couponList == null || couponList.size() == 0) {
            return 2;
        }

        //2.根据userId和code进行查询，查询当前用户是否持有该优惠券；
        //若持有优惠券，则返回 1；
        CouponUserExample userExample = new CouponUserExample();
        userExample.createCriteria()
                .andUserIdEqualTo(userId)
                .andDeletedEqualTo(false)
                .andUsedTimeIsNull()
                .andEndTimeGreaterThan(date);
        List<CouponUser> couponUsers = userMapper.selectByExample(userExample);

        if (couponUsers != null && couponUsers.size() != 0) {
            //用户持有有效的优惠券
            //获取当前用户持有的优惠券couponIds
            List<Integer> couponIds = new ArrayList<>();
            for (CouponUser couponUser : couponUsers) {
                couponIds.add(couponUser.getCouponId());
            }
            //根据couponId确认当前用户是否持有该兑换码；
            couponExample.clear();
            CouponExample.Criteria criteria = couponExample.createCriteria();
            criteria
                    .andDeletedEqualTo(false)
                    .andCodeEqualTo(code)
                    .andEndTimeGreaterThan(date)
                    .andIdIn(couponIds);
            List<Coupon> coupons = couponMapper.selectByExample(couponExample);
            if (coupons != null && coupons.size() != 0) {
                return 1;
            }
        }

        //3.至此，优惠券code正确，且用户未持有
        //在coupon_user表中插入该coupon
        //3.1 先获取当前兑换码所对应的coupon信息；
        couponExample.clear();
        couponExample.createCriteria()
                .andDeletedEqualTo(false)
                .andCodeEqualTo(code)
                .andEndTimeGreaterThan(date);
        List<Coupon> coupons = couponMapper.selectByExample(couponExample);
        for (Coupon coupon : coupons) {
            CouponUser user = new CouponUser();
            user.setUserId(userId);
            user.setCouponId(coupon.getId());
            user.setStatus(coupon.getStatus());
            user.setStartTime(coupon.getStartTime());
            user.setEndTime(coupon.getEndTime());
            user.setAddTime(date);
            user.setDeleted(false);
            userMapper.insertSelective(user);
        }

        return 0;
    }
}
